/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ohos.opengl;

import ohos.media.image.PixelMap;

public class GLUtils {

    /**
     * Temporary memory for operations that need temporary matrix data.
     */
    private final static float[] sTemp = new float[32];

    static {
        System.loadLibrary("glutils");
    }

    /**
     * @deprecated All methods are static, do not instantiate this class.
     */
    @Deprecated
    public GLUtils() {
    }

//    /**
//     * Multiplies two 4x4 matrices together and stores the result in a third 4x4
//     * matrix. In matrix notation: result = lhs x rhs. Due to the way
//     * matrix multiplication works, the result matrix will have the same
//     * effect as first multiplying by the rhs matrix, then multiplying by
//     * the lhs matrix. This is the opposite of what you might expect.
//     * <p>
//     * The same float array may be passed for result, lhs, and/or rhs. However,
//     * the result element values are undefined if the result elements overlap
//     * either the lhs or rhs elements.
//     *
//     * @param result The float array that holds the result.
//     * @param resultOffset The offset into the result array where the result is
//     *        stored.
//     * @param lhs The float array that holds the left-hand-side matrix.
//     * @param lhsOffset The offset into the lhs array where the lhs is stored
//     * @param rhs The float array that holds the right-hand-side matrix.
//     * @param rhsOffset The offset into the rhs array where the rhs is stored.
//     *
//     * @throws IllegalArgumentException if result, lhs, or rhs are null, or if
//     * resultOffset + 16 > result.length or lhsOffset + 16 > lhs.length or
//     * rhsOffset + 16 > rhs.length.
//     */
//
//    public static native void multiplyMM(float[] result, int resultOffset,
//            float[] lhs, int lhsOffset, float[] rhs, int rhsOffset);

    public static native void texImage2D(int target, int level, int internalformat,
                                         PixelMap bitmap, int type, int border);

    /**
     * Computes the length of a vector.
     *
     * @param x x coordinate of a vector
     * @param y y coordinate of a vector
     * @param z z coordinate of a vector
     * @return the length of a vector
     */
    // public static float length(float x, float y, float z) {
    //     return (float) Math.sqrt(x * x + y * y + z * z);
    //  }

    /**
     * Rotates matrix m by angle a (in degrees) around the axis (x, y, z).
     * <p>
     * m and rm must not overlap.
     *
     * @param rm returns the result
     * @param rmOffset index into rm where the result matrix starts
     * @param m source matrix
     * @param mOffset index into m where the source matrix starts
     * @param a angle to rotate in degrees
     * @param x X axis component
     * @param y Y axis component
     * @param z Z axis component
     */
//    public static void rotateM(float[] rm, int rmOffset,
//            float[] m, int mOffset,
//            float a, float x, float y, float z) {
//        synchronized(sTemp) {
//            setRotateM(sTemp, 0, a, x, y, z);
//            multiplyMM(rm, rmOffset, m, mOffset, sTemp, 0);
//        }
//    }

    /**
     * Rotates matrix m in place by angle a (in degrees)
     * around the axis (x, y, z).
     *
     * @param m source matrix
     * @param mOffset index into m where the matrix starts
     * @param a angle to rotate in degrees
     * @param x X axis component
     * @param y Y axis component
     * @param z Z axis component
     */
//    public static void rotateM(float[] m, int mOffset,
//            float a, float x, float y, float z) {
//        synchronized(sTemp) {
//            setRotateM(sTemp, 0, a, x, y, z);
//            multiplyMM(sTemp, 16, m, mOffset, sTemp, 0);
//            System.arraycopy(sTemp, 16, m, mOffset, 16);
//        }
//    }

    /**
     * Creates a matrix for rotation by angle a (in degrees)
     * around the axis (x, y, z).
     * <p>
     * An optimized path will be used for rotation about a major axis
     * (e.g. x=1.0f y=0.0f z=0.0f).
     *
     * @param rm returns the result
     * @param rmOffset index into rm where the result matrix starts
     * @param a angle to rotate in degrees
     * @param x X axis component
     * @param y Y axis component
     * @param z Z axis component
     */
//    public static void setRotateM(float[] rm, int rmOffset,
//            float a, float x, float y, float z) {
//        rm[rmOffset + 3] = 0;
//        rm[rmOffset + 7] = 0;
//        rm[rmOffset + 11]= 0;
//        rm[rmOffset + 12]= 0;
//        rm[rmOffset + 13]= 0;
//        rm[rmOffset + 14]= 0;
//        rm[rmOffset + 15]= 1;
//        a *= (float) (Math.PI / 180.0f);
//        float s = (float) Math.sin(a);
//        float c = (float) Math.cos(a);
//        if (1.0f == x && 0.0f == y && 0.0f == z) {
//            rm[rmOffset + 5] = c;   rm[rmOffset + 10]= c;
//            rm[rmOffset + 6] = s;   rm[rmOffset + 9] = -s;
//            rm[rmOffset + 1] = 0;   rm[rmOffset + 2] = 0;
//            rm[rmOffset + 4] = 0;   rm[rmOffset + 8] = 0;
//            rm[rmOffset + 0] = 1;
//        } else if (0.0f == x && 1.0f == y && 0.0f == z) {
//            rm[rmOffset + 0] = c;   rm[rmOffset + 10]= c;
//            rm[rmOffset + 8] = s;   rm[rmOffset + 2] = -s;
//            rm[rmOffset + 1] = 0;   rm[rmOffset + 4] = 0;
//            rm[rmOffset + 6] = 0;   rm[rmOffset + 9] = 0;
//            rm[rmOffset + 5] = 1;
//        } else if (0.0f == x && 0.0f == y && 1.0f == z) {
//            rm[rmOffset + 0] = c;   rm[rmOffset + 5] = c;
//            rm[rmOffset + 1] = s;   rm[rmOffset + 4] = -s;
//            rm[rmOffset + 2] = 0;   rm[rmOffset + 6] = 0;
//            rm[rmOffset + 8] = 0;   rm[rmOffset + 9] = 0;
//            rm[rmOffset + 10]= 1;
//        } else {
//            float len = length(x, y, z);
//            if (1.0f != len) {
//                float recipLen = 1.0f / len;
//                x *= recipLen;
//                y *= recipLen;
//                z *= recipLen;
//            }
//            float nc = 1.0f - c;
//            float xy = x * y;
//            float yz = y * z;
//            float zx = z * x;
//            float xs = x * s;
//            float ys = y * s;
//            float zs = z * s;
//            rm[rmOffset +  0] = x*x*nc +  c;
//            rm[rmOffset +  4] =  xy*nc - zs;
//            rm[rmOffset +  8] =  zx*nc + ys;
//            rm[rmOffset +  1] =  xy*nc + zs;
//            rm[rmOffset +  5] = y*y*nc +  c;
//            rm[rmOffset +  9] =  yz*nc - xs;
//            rm[rmOffset +  2] =  zx*nc - ys;
//            rm[rmOffset +  6] =  yz*nc + xs;
//            rm[rmOffset + 10] = z*z*nc +  c;
//        }
//    }
}
